package org.jdna.minecraft.tools;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Properties;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

public class Preferences {
	private static final String PROP_MINECRAFT_DIR = "minecraft.dir";
	private static final String PROP_MINECRAFT_MODS_DIR = "minecraft.mods.dir";
	private static final String PROP_CREATE_BACKUPS = "create.backups";
	private static final String PROP_CREATE_FULL_BACKUPS = "create.full.backups";
	
	private Logger log = Logger.getLogger(Preferences.class);
	private Properties props = new Properties();
	private File preferencesFile=null;
	private File preferencesDir=null;
	
	public Preferences(File preferencesDir) {
		this.preferencesDir = preferencesDir;
		if (!preferencesDir.exists()) {
			preferencesDir.mkdirs();
		}
		preferencesFile = new File(preferencesDir, "preferences.properties");
		if (preferencesFile.exists()) {
			try {
				log.info("Loading preferences: " + preferencesFile);
				props.load(new FileInputStream(preferencesFile));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		Runtime.getRuntime().addShutdownHook(new Thread() {
			@Override
			public void run() {
				store();
			}
		});
	}

	public File getPreferencesFile() {
		return preferencesFile;
	}

	public File getPreferencesDir() {
		return preferencesDir;
	}
	
	public String getMinecraftDir() {
		String md = props.getProperty(PROP_MINECRAFT_DIR);
		if (StringUtils.isEmpty(md)) {
			// Check windows
			String appdata = System.getenv("appdata");
			if (!StringUtils.isEmpty(appdata)) {
				 File dir = new File(appdata, ".minecraft");
				 File jar = getMinecraftJar(dir);
				 if (jar.exists()) {
					 md = dir.getAbsolutePath();
				 }
			}
			
			// check mac
			if (StringUtils.isEmpty(md)) {
				File dir = new File(getHomedir(), "/Library/Application Support/minecraft/");
				if (dir.exists()) {
					File jar = getMinecraftJar(dir);
					if (jar.exists()) {
						md = dir.getAbsolutePath();
					}
				}
			}
			
			// check linux
			if (StringUtils.isEmpty(md)) {
				File dir = new File(getHomedir(), ".minecraft");
				if (dir.exists()) {
					File jar = getMinecraftJar(dir);
					if (jar.exists()) {
						md = dir.getAbsolutePath();
					}
				}
			}
		}
		return md;
	}
	
	private File getMinecraftJar(File dir) {
		 return new File(dir, "bin/minecraft.jar");
	}

	public String getMinecraftModsDir() {
		String dir = props.getProperty(PROP_MINECRAFT_MODS_DIR);
		if (dir==null) {
			dir = ".";
		}
		return dir;
	}
	
	public void setMinecraftModsDir(File dir) {
		props.setProperty(PROP_MINECRAFT_MODS_DIR, dir.getAbsolutePath());
	}
	
	public void setMinecraftDir(String dir) {
		if (dir==null) return;
		File f = new File(dir);
		if (!f.exists() && !f.isDirectory()) {
			log.warn("invalid minecraft dir: " + dir);
			return;
		}
		props.setProperty(PROP_MINECRAFT_DIR, dir);
	}
	
	public File getMinecraftDirAsFile() {
		String dir = getMinecraftDir();
		if (dir!=null) {
			return new File(dir);
		} else {
			return new File(".");
		}
	}
	
	public String getDonateLink() {
		return "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=36M332BKZTLJU&lc=CA&item_name=Stuckless%20Mod%20Manager%20for%20Minecraft&item_number=3%2e14159&amount=5%2e00&currency_code=CAD&currency_code=CAD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted";		
	}
	
	public File getMinecraftJar() {
		return getMinecraftJar(getMinecraftDirAsFile());
	}
	
	public static File getHomedir() {
		return new File(System.getProperty("user.home"));
	}
	
	public boolean isValidMinecraftDir(File dir) {
		return (dir!=null && dir.exists() && getMinecraftJar(dir).exists());
	}
	
	public File getTmpArea() {
		File f = new File(preferencesDir, "tmp");
		if (!f.exists()) {
			f.mkdirs();
		}
		return f;
	}

	public File getBackupDir() {
		File dir =  new File(getPreferencesDir(), "backups");
		try {
			FileUtils.forceMkdir(dir);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return dir;
	}

	public void setCreateBackupsEnabled(boolean selected) {
		props.setProperty(PROP_CREATE_BACKUPS, String.valueOf(selected));
	}
	
	public boolean isCreateBackupsEnabled() {
		String s = props.getProperty(PROP_CREATE_BACKUPS);
		if (StringUtils.isEmpty(s)) return true;
		return BooleanUtils.toBoolean(s);
	}

	public boolean isCreateFullBackupsEnabled() {
		String s = props.getProperty(PROP_CREATE_FULL_BACKUPS);
		if (StringUtils.isEmpty(s)) return false;
		return BooleanUtils.toBoolean(s);
	}

	public void setCreateFullBackupsEnabled(boolean selected) {
		props.setProperty(PROP_CREATE_FULL_BACKUPS, String.valueOf(selected));
	}

	public void store() {
		if (preferencesFile!=null) {
			try {
				FileOutputStream fos = new FileOutputStream(preferencesFile);
				props.store(fos, "Stuckless Mod Manager Prefrences");
				fos.flush();
				fos.close();
				log.info("Saving Preferences");
			} catch (Throwable t) {
				log.warn("Failed to save preferences", t);
			}
		}
	}

	public URL getModsUrl() {
		return this.getClass().getClassLoader().getResource("res/xml/mods.xml");
	}
}
